local AnimTime = 0
local Replaying = false
local LReplaying = false
local ReplayStart = os.clock()

function ReplayMovement()
	if Replaying then
		AnimTime = os.clock() - ReplayStart
		
		for _, v in pairs( ents.FindByClass("prop_physics") ) do
			if v:GetNWBool("GAAnimated") and v.GAMovement then
				local data, i = GetMovementData( v, AnimTime )
				
				//If the props is off position/angle, correct this
				local TotalVelocity = (math.abs(v:GetPhysicsObject():GetVelocity().x) + math.abs(v:GetPhysicsObject():GetVelocity().y) + math.abs(v:GetPhysicsObject():GetVelocity().z))
				if v:GetPos():Distance( data.Position ) > TotalVelocity then
					v:SetPos( data.Position )
				end
				v:SetAngles( data.Angles )
				
				ResumeMovement( v, data.Velocity, data.AngleVelocity )
				
				if i == #v.GAMovement then
					Replaying = false
					
					//Make unrecorded motion continue from the last recorded point
					for _, e in pairs( ents.FindByClass("prop_physics") ) do
						if e:GetNWBool("GAAnimated") then
							ResumeMovement( e, data.Velocity, data.AngleVelocity )
						end
					end
				end
			end
		end
	end
	
	//Replay finished?
	if !Replaying and LReplaying == true then
		for _, v in pairs(player.GetAll()) do v:ChatPrint( "Replay finished after " .. math.Round(os.clock() - ReplayStart) .. " seconds" ) end
	end
	
	LReplaying = Replaying
end
hook.Add( "Think", "PlayMovementData", ReplayMovement )

function StartReplaying()
	AnimTime = 0
	Replaying = true
	ReplayStart = os.clock()
	
	for _, e in pairs( ents.FindByClass("prop_physics") ) do
		if e:GetNWBool("GAAnimated") then
			local data = GetMovementData( e, 0 )
			e:SetPos( data.Position )
			e:SetAngles( data.Angles )
		end
	end
end

function GetMovementData( ent, time )
	local BestSoFar = nil
	local BestID = 0
	
	for i, data in pairs( ent.GAMovement ) do
		if data.Time <= time then
			BestSoFar = data
			BestID = i
		end
	end
	
	return BestSoFar, BestID
end

function ResumeMovement( ent, vel, angvel )
	local phys = ent:GetPhysicsObject()
	phys:Wake()
	phys:SetVelocity( vel )
	phys:AddAngleVelocity( phys:GetAngleVelocity() *-1 + angvel )
end